package lex.mxbeans.utils;

import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.LogManager;
import java.util.logging.LoggingMXBean;

import org.lex.utils.MethodNameFormatter;


public class MXBeansUtils
{
	private static final Object[] EMPTY = new Object[0];

	public static void main( String[] args )
	{
		test();
	}

	public static void test()
	{
		for( MXBeanInfo p : getAllMXBeans() )
		{
			System.out.println( format( p ) );
		}
	}

	static StringBuilder buf = new StringBuilder();

	static String format( MXBeanInfo bean )
	{
		buf.setLength( 0 );
		buf.append( bean.getName() ).append( ": " );
		for( Object o : bean.getBeans() )
			buf.append( o.getClass().getSimpleName() ).append( ", " );
		return buf.toString();
	}

	public static MXBeanInfo[] getAllMXBeans()
	{
		List<MXBeanInfo> list = new ArrayList<MXBeanInfo>();
		list.add( new MXBeanInfo(
			MethodNameFormatter.format( LoggingMXBean.class.getSimpleName() ), LogManager
				.getLoggingMXBean() ) );
		Method[] methods = ManagementFactory.class.getMethods();
		for( Method m : methods )
		{
			if( (0 == m.getParameterTypes().length)
					&& (false == Void.class.isAssignableFrom( m.getReturnType() )) )
			{
				try
				{
					Object value = m.invoke( null, EMPTY );
					String name = MethodNameFormatter.format( m.getName() );
					list.add( new MXBeanInfo( name, value ) );
				}
				catch( Exception e )
				{}
			}
		}
		return list.toArray( new MXBeanInfo[list.size()] );
	}

	private MXBeansUtils()
	{}

	private static boolean accept( Class<?> clz )
	{
		return clz.isInterface() && clz.getName().startsWith( "java" );
	}

	public static Class<?> findSuperClass( Class<?> clz )
	{
		if( accept( clz ) )
			return clz;
		List<Class<?>> list = new ArrayList<Class<?>>();
		Collections.addAll( list, clz.getClasses() );
		Collections.addAll( list, clz.getInterfaces() );
		for( Class<?> c : list )
		{
			if( accept( c ) )
				return c;
		}
		Class<?> find = null;
		for( Class<?> c : list )
		{
			find = findSuperClass( c );
			if( null != find )
				return find;
		}
		return null;
	}
}
